/*
#
#  Copyright 2011 Matthew Jannace
#
#  This file is part of RoboCode BlackHoleAgent
#
#  RoboCode BlackHoleAgent is free software: you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation, either version 3 of the
#  License, or (at your option) any later version.
#
#  RoboCode BlackHoleAgent is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#  General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with RoboCode BlackHoleAgent. If not, see
#  <http://www.gnu.org/licenses/>.
#
 */
package com.jannaceltd.TeamBlackHoleBeer.Utilities;

import java.awt.geom.Point2D;

/**
 * Class for central location of methods that help with math calculations
 * @author Matthew Jannace <mjannace@gmail.com>
 * @version 1.0
 */
public class MathUtils {

    /**
     * Calculates the Angle between Point1 and Point2
     * @param p2
     * @param p1
     * @return Angle between Point1 and Point2
     */
    public static double calcAngle(Point2D.Double p2, Point2D.Double p1) {
        return Math.atan2(p2.x - p1.x, p2.y - p1.y);
    }

    /**
     * Calculates the Absolute Bearing between a Source location and Target location
     * @param source 
     * @param target 
     * @return Angle between Point1 and Point2
     */
    public static double absoluteBearing(Point2D source, Point2D target) {
        return Math.atan2(target.getX() - source.getX(), target.getY() - source.getY());
    }

    /**
     * Projects the location of point based on the source location and the angle
     * and length of a line from that source location
     * @param sourceLocation
     * @param angle
     * @param length
     * @return Projected XY location
     */
    public static Point2D.Double project(Point2D.Double sourceLocation, double angle, double length) {
        return new Point2D.Double(sourceLocation.getX() + Math.sin(angle) * length,
                sourceLocation.getY() + Math.cos(angle) * length);
    }

    /**
     * Calculates A bullets Velocity give a power
     * @param power
     * @return bullets Velocity
     */
    public static double bulletVelocity(double power) {
        return 20 - 3 * power;
    }

    /**
     *  The maximum Escape Angle of a Bullet
     * @param power
     * @return
     */
    public static double maxEscapeAngle(double power) {
        return Math.asin(8 / bulletVelocity(power));
    }

    /**
     * returns positive signed integer
     * @param v
     * @return positive sign of param v
     */
    public static int sign(double v) {
        return v < 0 ? -1 : 1;
    }

    /**
     * Returns a number not greater than the max and not less than the min
     * @param v
     * @param min
     * @param max
     * @return Max <= v >=  Min
     */
    public static int minMax(int v, int min, int max) {
        return Math.max(min, Math.min(max, v));
    }

    /**
     * Returns a number not greater than the max and not less than the min
     * @param v
     * @param min
     * @param max
     * @return Max <= v >=  Min
     */
    public static double Limit(double v, double min, double max) {
        return Math.max(min, Math.min(max, v));
    }

    /**
     * Calculates the damage of a bullet given the power
     * @param power
     * @return bullet damage
     */
    public static double bulletDamage(double power) {
        return (4 * power + 2 * Math.max((power - 1), 0));
    }

    /**
     * Calculates the wall damage of a bullet given the velocity
     * @param velocity
     * @return wall damage
     */
    public static double WallDamage(double velocity) {
        return Math.max(Math.abs(velocity) * 0.5 - 1, 0);
    }
}
